using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Serialization;
using Nsb;
using Nsb.Classes;
using ThemeChain;
using YoshiBase.Classes;
using jQueryApi;

namespace Yoshi.Fb
{
    [IgnoreNamespace]
    public class FbFileData : FbIdentity
    {
        private const string Password = "SuperBaby";

        private static string PutUrl { get { return Uri.Join(ThemeBase.AppUri, "/file.put.php"); } }

        internal void RetrieveBlob(FnDelegate1 fn)
        {
            RetrieveFileBlob(fn);
        }

        private void RetrieveFileBlob(FnDelegate1 fn)
        {
            Dictionary<string, string> payload = new Dictionary<string, string>();
            payload["password"] = Password;
            payload["path"] = Uri.DbPath("");
            payload["file"] = "FB" + FbBaseUser.id + ".json";

            jQueryAjaxOptions options = new jQueryAjaxOptions();
            options.Url = Uri.Join("/yoshi/", ThemeBase.AppUri, "/file.get.php");
            options.Data = payload;
            options.DataType = "jsonp";
            options.Type = "GET";

            options.Success =
                delegate(object fbo, string textStatus, jQueryXmlHttpRequest request1)
                {
                    YoshiAuthData data = (YoshiAuthData)Unpackage((string)Type.GetField(fbo, "content"));
                    //Inform.Trace("fbo=[{0}]", Json.Stringify(data));

                    //if ((bool)Type.GetField(fbo, "result") != true || data.User.id != FbBaseUser.id)
                    //{
                    //    throw new Exception(Exceptions.BlobLoadError);
                    //}

                    if (Script.IsValue(fn))
                        fn(data);
                };

            options.Error =
                delegate(jQueryXmlHttpRequest request, string textStatus, Exception error)
                {
                    Inform.Error("Error saving blob to a file error=" + textStatus + " : " + error + " : " + request.ResponseText);
                };

            jQuery.Ajax(options);
        }

        [AlternateSignature]
        internal extern void SaveBlob(object blob);

        // ReSharper disable UnusedMember.Global
        internal void SaveBlob(object blob, FnDelegate1 fn)
        // ReSharper restore UnusedMember.Global
        {
            SaveFileBlob(blob, fn);
        }

        private void SaveFileBlob(object blob, FnDelegate1 fn)
        {
            string blob64 = Repackage(blob);

            Dictionary<string, string> payload = new Dictionary<string, string>();
            payload["password"] = Password;
            payload["createFile"] = "true";
            payload["createPath"] = "true";
            payload["path"] = Uri.DbPath("");
            payload["file"] = "FB" + FbBaseUser.id + ".json";
            payload["content"] = blob64;

            jQueryAjaxOptions options = new jQueryAjaxOptions();
            options.Url = PutUrl;
            options.Data = payload;
            //options.DataType = "json";
            options.Type = "POST";

            options.Success =
                delegate(object fbo, string textStatus, jQueryXmlHttpRequest request1)
                {
                    try
                    {
                        if (!Script.IsValue(fbo) || (bool) Type.GetField(fbo, "result") != true)
                        {
                            throw new Exception(Exceptions.BlobSaveError);
                        }
                    }
                    catch
                    {
                        throw new Exception(Exceptions.BlobSaveError);
                    }

                    if (Script.IsValue(fn))
                        fn(fbo);
                };

            options.Error =
                delegate(jQueryXmlHttpRequest request, string textStatus, Exception error)
                {
                    Inform.Error("Error saving blob to a file error=" + textStatus + " : " + error + " : " + request);
                };

            jQuery.Ajax(options);
        }


        private string Repackage(object blob)
        {
            return Encode(Json.Stringify(blob));
        }

        private object Unpackage(string s)
        {
            if (!String.IsNullOrEmpty(s))
                return Json.Parse(Decode(s));
            return "";
        }

        private string Encode(string s)
        {
            return Encoder.Encode64(Encoder.LzwEncode(s));
        }

        private string Decode(string s)
        {
            return Encoder.LzwDecode(Encoder.Decode64(s));
        }
    }
}